home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / share / gettext / intl / loadmsgcat.c < prev    next >
Encoding:
C/C++ Source or Header  |  2007-03-05  |  33.3 KB  |  1,334 lines

  1. /* Load needed message catalogs.
  2.    Copyright (C) 1995-1999, 2000-2005 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify it
  5.    under the terms of the GNU Library General Public License as published
  6.    by the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.    Library General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU Library General Public
  15.    License along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  17.    USA.  */
  18.  
  19. /* Tell glibc's <string.h> to provide a prototype for mempcpy().
  20.    This must come before <config.h> because <config.h> may include
  21.    <features.h>, and once <features.h> has been included, it's too late.  */
  22. #ifndef _GNU_SOURCE
  23. # define _GNU_SOURCE    1
  24. #endif
  25.  
  26. #ifdef HAVE_CONFIG_H
  27. # include <config.h>
  28. #endif
  29.  
  30. #include <ctype.h>
  31. #include <errno.h>
  32. #include <fcntl.h>
  33. #include <sys/types.h>
  34. #include <sys/stat.h>
  35.  
  36. #ifdef __GNUC__
  37. # undef  alloca
  38. # define alloca __builtin_alloca
  39. # define HAVE_ALLOCA 1
  40. #else
  41. # ifdef _MSC_VER
  42. #  include <malloc.h>
  43. #  define alloca _alloca
  44. # else
  45. #  if defined HAVE_ALLOCA_H || defined _LIBC
  46. #   include <alloca.h>
  47. #  else
  48. #   ifdef _AIX
  49.  #pragma alloca
  50. #   else
  51. #    ifndef alloca
  52. char *alloca ();
  53. #    endif
  54. #   endif
  55. #  endif
  56. # endif
  57. #endif
  58.  
  59. #include <stdlib.h>
  60. #include <string.h>
  61.  
  62. #if defined HAVE_UNISTD_H || defined _LIBC
  63. # include <unistd.h>
  64. #endif
  65.  
  66. #ifdef _LIBC
  67. # include <langinfo.h>
  68. # include <locale.h>
  69. #endif
  70.  
  71. #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \
  72.     || (defined _LIBC && defined _POSIX_MAPPED_FILES)
  73. # include <sys/mman.h>
  74. # undef HAVE_MMAP
  75. # define HAVE_MMAP    1
  76. #else
  77. # undef HAVE_MMAP
  78. #endif
  79.  
  80. #if defined HAVE_STDINT_H_WITH_UINTMAX || defined _LIBC
  81. # include <stdint.h>
  82. #endif
  83. #if defined HAVE_INTTYPES_H || defined _LIBC
  84. # include <inttypes.h>
  85. #endif
  86.  
  87. #include "gmo.h"
  88. #include "gettextP.h"
  89. #include "hash-string.h"
  90. #include "plural-exp.h"
  91.  
  92. #ifdef _LIBC
  93. # include "../locale/localeinfo.h"
  94. # include <not-cancel.h>
  95. #endif
  96.  
  97. /* Handle multi-threaded applications.  */
  98. #ifdef _LIBC
  99. # include <bits/libc-lock.h>
  100. #else
  101. # include "lock.h"
  102. #endif
  103.  
  104. /* Provide fallback values for macros that ought to be defined in <inttypes.h>.
  105.    Note that our fallback values need not be literal strings, because we don't
  106.    use them with preprocessor string concatenation.  */
  107. #if !defined PRId8 || PRI_MACROS_BROKEN
  108. # undef PRId8
  109. # define PRId8 "d"
  110. #endif
  111. #if !defined PRIi8 || PRI_MACROS_BROKEN
  112. # undef PRIi8
  113. # define PRIi8 "i"
  114. #endif
  115. #if !defined PRIo8 || PRI_MACROS_BROKEN
  116. # undef PRIo8
  117. # define PRIo8 "o"
  118. #endif
  119. #if !defined PRIu8 || PRI_MACROS_BROKEN
  120. # undef PRIu8
  121. # define PRIu8 "u"
  122. #endif
  123. #if !defined PRIx8 || PRI_MACROS_BROKEN
  124. # undef PRIx8
  125. # define PRIx8 "x"
  126. #endif
  127. #if !defined PRIX8 || PRI_MACROS_BROKEN
  128. # undef PRIX8
  129. # define PRIX8 "X"
  130. #endif
  131. #if !defined PRId16 || PRI_MACROS_BROKEN
  132. # undef PRId16
  133. # define PRId16 "d"
  134. #endif
  135. #if !defined PRIi16 || PRI_MACROS_BROKEN
  136. # undef PRIi16
  137. # define PRIi16 "i"
  138. #endif
  139. #if !defined PRIo16 || PRI_MACROS_BROKEN
  140. # undef PRIo16
  141. # define PRIo16 "o"
  142. #endif
  143. #if !defined PRIu16 || PRI_MACROS_BROKEN
  144. # undef PRIu16
  145. # define PRIu16 "u"
  146. #endif
  147. #if !defined PRIx16 || PRI_MACROS_BROKEN
  148. # undef PRIx16
  149. # define PRIx16 "x"
  150. #endif
  151. #if !defined PRIX16 || PRI_MACROS_BROKEN
  152. # undef PRIX16
  153. # define PRIX16 "X"
  154. #endif
  155. #if !defined PRId32 || PRI_MACROS_BROKEN
  156. # undef PRId32
  157. # define PRId32 "d"
  158. #endif
  159. #if !defined PRIi32 || PRI_MACROS_BROKEN
  160. # undef PRIi32
  161. # define PRIi32 "i"
  162. #endif
  163. #if !defined PRIo32 || PRI_MACROS_BROKEN
  164. # undef PRIo32
  165. # define PRIo32 "o"
  166. #endif
  167. #if !defined PRIu32 || PRI_MACROS_BROKEN
  168. # undef PRIu32
  169. # define PRIu32 "u"
  170. #endif
  171. #if !defined PRIx32 || PRI_MACROS_BROKEN
  172. # undef PRIx32
  173. # define PRIx32 "x"
  174. #endif
  175. #if !defined PRIX32 || PRI_MACROS_BROKEN
  176. # undef PRIX32
  177. # define PRIX32 "X"
  178. #endif
  179. #if !defined PRId64 || PRI_MACROS_BROKEN
  180. # undef PRId64
  181. # define PRId64 (sizeof (long) == 8 ? "ld" : "lld")
  182. #endif
  183. #if !defined PRIi64 || PRI_MACROS_BROKEN
  184. # undef PRIi64
  185. # define PRIi64 (sizeof (long) == 8 ? "li" : "lli")
  186. #endif
  187. #if !defined PRIo64 || PRI_MACROS_BROKEN
  188. # undef PRIo64
  189. # define PRIo64 (sizeof (long) == 8 ? "lo" : "llo")
  190. #endif
  191. #if !defined PRIu64 || PRI_MACROS_BROKEN
  192. # undef PRIu64
  193. # define PRIu64 (sizeof (long) == 8 ? "lu" : "llu")
  194. #endif
  195. #if !defined PRIx64 || PRI_MACROS_BROKEN
  196. # undef PRIx64
  197. # define PRIx64 (sizeof (long) == 8 ? "lx" : "llx")
  198. #endif
  199. #if !defined PRIX64 || PRI_MACROS_BROKEN
  200. # undef PRIX64
  201. # define PRIX64 (sizeof (long) == 8 ? "lX" : "llX")
  202. #endif
  203. #if !defined PRIdLEAST8 || PRI_MACROS_BROKEN
  204. # undef PRIdLEAST8
  205. # define PRIdLEAST8 "d"
  206. #endif
  207. #if !defined PRIiLEAST8 || PRI_MACROS_BROKEN
  208. # undef PRIiLEAST8
  209. # define PRIiLEAST8 "i"
  210. #endif
  211. #if !defined PRIoLEAST8 || PRI_MACROS_BROKEN
  212. # undef PRIoLEAST8
  213. # define PRIoLEAST8 "o"
  214. #endif
  215. #if !defined PRIuLEAST8 || PRI_MACROS_BROKEN
  216. # undef PRIuLEAST8
  217. # define PRIuLEAST8 "u"
  218. #endif
  219. #if !defined PRIxLEAST8 || PRI_MACROS_BROKEN
  220. # undef PRIxLEAST8
  221. # define PRIxLEAST8 "x"
  222. #endif
  223. #if !defined PRIXLEAST8 || PRI_MACROS_BROKEN
  224. # undef PRIXLEAST8
  225. # define PRIXLEAST8 "X"
  226. #endif
  227. #if !defined PRIdLEAST16 || PRI_MACROS_BROKEN
  228. # undef PRIdLEAST16
  229. # define PRIdLEAST16 "d"
  230. #endif
  231. #if !defined PRIiLEAST16 || PRI_MACROS_BROKEN
  232. # undef PRIiLEAST16
  233. # define PRIiLEAST16 "i"
  234. #endif
  235. #if !defined PRIoLEAST16 || PRI_MACROS_BROKEN
  236. # undef PRIoLEAST16
  237. # define PRIoLEAST16 "o"
  238. #endif
  239. #if !defined PRIuLEAST16 || PRI_MACROS_BROKEN
  240. # undef PRIuLEAST16
  241. # define PRIuLEAST16 "u"
  242. #endif
  243. #if !defined PRIxLEAST16 || PRI_MACROS_BROKEN
  244. # undef PRIxLEAST16
  245. # define PRIxLEAST16 "x"
  246. #endif
  247. #if !defined PRIXLEAST16 || PRI_MACROS_BROKEN
  248. # undef PRIXLEAST16
  249. # define PRIXLEAST16 "X"
  250. #endif
  251. #if !defined PRIdLEAST32 || PRI_MACROS_BROKEN
  252. # undef PRIdLEAST32
  253. # define PRIdLEAST32 "d"
  254. #endif
  255. #if !defined PRIiLEAST32 || PRI_MACROS_BROKEN
  256. # undef PRIiLEAST32
  257. # define PRIiLEAST32 "i"
  258. #endif
  259. #if !defined PRIoLEAST32 || PRI_MACROS_BROKEN
  260. # undef PRIoLEAST32
  261. # define PRIoLEAST32 "o"
  262. #endif
  263. #if !defined PRIuLEAST32 || PRI_MACROS_BROKEN
  264. # undef PRIuLEAST32
  265. # define PRIuLEAST32 "u"
  266. #endif
  267. #if !defined PRIxLEAST32 || PRI_MACROS_BROKEN
  268. # undef PRIxLEAST32
  269. # define PRIxLEAST32 "x"
  270. #endif
  271. #if !defined PRIXLEAST32 || PRI_MACROS_BROKEN
  272. # undef PRIXLEAST32
  273. # define PRIXLEAST32 "X"
  274. #endif
  275. #if !defined PRIdLEAST64 || PRI_MACROS_BROKEN
  276. # undef PRIdLEAST64
  277. # define PRIdLEAST64 PRId64
  278. #endif
  279. #if !defined PRIiLEAST64 || PRI_MACROS_BROKEN
  280. # undef PRIiLEAST64
  281. # define PRIiLEAST64 PRIi64
  282. #endif
  283. #if !defined PRIoLEAST64 || PRI_MACROS_BROKEN
  284. # undef PRIoLEAST64
  285. # define PRIoLEAST64 PRIo64
  286. #endif
  287. #if !defined PRIuLEAST64 || PRI_MACROS_BROKEN
  288. # undef PRIuLEAST64
  289. # define PRIuLEAST64 PRIu64
  290. #endif
  291. #if !defined PRIxLEAST64 || PRI_MACROS_BROKEN
  292. # undef PRIxLEAST64
  293. # define PRIxLEAST64 PRIx64
  294. #endif
  295. #if !defined PRIXLEAST64 || PRI_MACROS_BROKEN
  296. # undef PRIXLEAST64
  297. # define PRIXLEAST64 PRIX64
  298. #endif
  299. #if !defined PRIdFAST8 || PRI_MACROS_BROKEN
  300. # undef PRIdFAST8
  301. # define PRIdFAST8 "d"
  302. #endif
  303. #if !defined PRIiFAST8 || PRI_MACROS_BROKEN
  304. # undef PRIiFAST8
  305. # define PRIiFAST8 "i"
  306. #endif
  307. #if !defined PRIoFAST8 || PRI_MACROS_BROKEN
  308. # undef PRIoFAST8
  309. # define PRIoFAST8 "o"
  310. #endif
  311. #if !defined PRIuFAST8 || PRI_MACROS_BROKEN
  312. # undef PRIuFAST8
  313. # define PRIuFAST8 "u"
  314. #endif
  315. #if !defined PRIxFAST8 || PRI_MACROS_BROKEN
  316. # undef PRIxFAST8
  317. # define PRIxFAST8 "x"
  318. #endif
  319. #if !defined PRIXFAST8 || PRI_MACROS_BROKEN
  320. # undef PRIXFAST8
  321. # define PRIXFAST8 "X"
  322. #endif
  323. #if !defined PRIdFAST16 || PRI_MACROS_BROKEN
  324. # undef PRIdFAST16
  325. # define PRIdFAST16 "d"
  326. #endif
  327. #if !defined PRIiFAST16 || PRI_MACROS_BROKEN
  328. # undef PRIiFAST16
  329. # define PRIiFAST16 "i"
  330. #endif
  331. #if !defined PRIoFAST16 || PRI_MACROS_BROKEN
  332. # undef PRIoFAST16
  333. # define PRIoFAST16 "o"
  334. #endif
  335. #if !defined PRIuFAST16 || PRI_MACROS_BROKEN
  336. # undef PRIuFAST16
  337. # define PRIuFAST16 "u"
  338. #endif
  339. #if !defined PRIxFAST16 || PRI_MACROS_BROKEN
  340. # undef PRIxFAST16
  341. # define PRIxFAST16 "x"
  342. #endif
  343. #if !defined PRIXFAST16 || PRI_MACROS_BROKEN
  344. # undef PRIXFAST16
  345. # define PRIXFAST16 "X"
  346. #endif
  347. #if !defined PRIdFAST32 || PRI_MACROS_BROKEN
  348. # undef PRIdFAST32
  349. # define PRIdFAST32 "d"
  350. #endif
  351. #if !defined PRIiFAST32 || PRI_MACROS_BROKEN
  352. # undef PRIiFAST32
  353. # define PRIiFAST32 "i"
  354. #endif
  355. #if !defined PRIoFAST32 || PRI_MACROS_BROKEN
  356. # undef PRIoFAST32
  357. # define PRIoFAST32 "o"
  358. #endif
  359. #if !defined PRIuFAST32 || PRI_MACROS_BROKEN
  360. # undef PRIuFAST32
  361. # define PRIuFAST32 "u"
  362. #endif
  363. #if !defined PRIxFAST32 || PRI_MACROS_BROKEN
  364. # undef PRIxFAST32
  365. # define PRIxFAST32 "x"
  366. #endif
  367. #if !defined PRIXFAST32 || PRI_MACROS_BROKEN
  368. # undef PRIXFAST32
  369. # define PRIXFAST32 "X"
  370. #endif
  371. #if !defined PRIdFAST64 || PRI_MACROS_BROKEN
  372. # undef PRIdFAST64
  373. # define PRIdFAST64 PRId64
  374. #endif
  375. #if !defined PRIiFAST64 || PRI_MACROS_BROKEN
  376. # undef PRIiFAST64
  377. # define PRIiFAST64 PRIi64
  378. #endif
  379. #if !defined PRIoFAST64 || PRI_MACROS_BROKEN
  380. # undef PRIoFAST64
  381. # define PRIoFAST64 PRIo64
  382. #endif
  383. #if !defined PRIuFAST64 || PRI_MACROS_BROKEN
  384. # undef PRIuFAST64
  385. # define PRIuFAST64 PRIu64
  386. #endif
  387. #if !defined PRIxFAST64 || PRI_MACROS_BROKEN
  388. # undef PRIxFAST64
  389. # define PRIxFAST64 PRIx64
  390. #endif
  391. #if !defined PRIXFAST64 || PRI_MACROS_BROKEN
  392. # undef PRIXFAST64
  393. # define PRIXFAST64 PRIX64
  394. #endif
  395. #if !defined PRIdMAX || PRI_MACROS_BROKEN
  396. # undef PRIdMAX
  397. # define PRIdMAX (sizeof (uintmax_t) == sizeof (long) ? "ld" : "lld")
  398. #endif
  399. #if !defined PRIiMAX || PRI_MACROS_BROKEN
  400. # undef PRIiMAX
  401. # define PRIiMAX (sizeof (uintmax_t) == sizeof (long) ? "li" : "lli")
  402. #endif
  403. #if !defined PRIoMAX || PRI_MACROS_BROKEN
  404. # undef PRIoMAX
  405. # define PRIoMAX (sizeof (uintmax_t) == sizeof (long) ? "lo" : "llo")
  406. #endif
  407. #if !defined PRIuMAX || PRI_MACROS_BROKEN
  408. # undef PRIuMAX
  409. # define PRIuMAX (sizeof (uintmax_t) == sizeof (long) ? "lu" : "llu")
  410. #endif
  411. #if !defined PRIxMAX || PRI_MACROS_BROKEN
  412. # undef PRIxMAX
  413. # define PRIxMAX (sizeof (uintmax_t) == sizeof (long) ? "lx" : "llx")
  414. #endif
  415. #if !defined PRIXMAX || PRI_MACROS_BROKEN
  416. # undef PRIXMAX
  417. # define PRIXMAX (sizeof (uintmax_t) == sizeof (long) ? "lX" : "llX")
  418. #endif
  419. #if !defined PRIdPTR || PRI_MACROS_BROKEN
  420. # undef PRIdPTR
  421. # define PRIdPTR \
  422.   (sizeof (void *) == sizeof (long) ? "ld" : \
  423.    sizeof (void *) == sizeof (int) ? "d" : \
  424.    "lld")
  425. #endif
  426. #if !defined PRIiPTR || PRI_MACROS_BROKEN
  427. # undef PRIiPTR
  428. # define PRIiPTR \
  429.   (sizeof (void *) == sizeof (long) ? "li" : \
  430.    sizeof (void *) == sizeof (int) ? "i" : \
  431.    "lli")
  432. #endif
  433. #if !defined PRIoPTR || PRI_MACROS_BROKEN
  434. # undef PRIoPTR
  435. # define PRIoPTR \
  436.   (sizeof (void *) == sizeof (long) ? "lo" : \
  437.    sizeof (void *) == sizeof (int) ? "o" : \
  438.    "llo")
  439. #endif
  440. #if !defined PRIuPTR || PRI_MACROS_BROKEN
  441. # undef PRIuPTR
  442. # define PRIuPTR \
  443.   (sizeof (void *) == sizeof (long) ? "lu" : \
  444.    sizeof (void *) == sizeof (int) ? "u" : \
  445.    "llu")
  446. #endif
  447. #if !defined PRIxPTR || PRI_MACROS_BROKEN
  448. # undef PRIxPTR
  449. # define PRIxPTR \
  450.   (sizeof (void *) == sizeof (long) ? "lx" : \
  451.    sizeof (void *) == sizeof (int) ? "x" : \
  452.    "llx")
  453. #endif
  454. #if !defined PRIXPTR || PRI_MACROS_BROKEN
  455. # undef PRIXPTR
  456. # define PRIXPTR \
  457.   (sizeof (void *) == sizeof (long) ? "lX" : \
  458.    sizeof (void *) == sizeof (int) ? "X" : \
  459.    "llX")
  460. #endif
  461.  
  462. /* @@ end of prolog @@ */
  463.  
  464. #ifdef _LIBC
  465. /* Rename the non ISO C functions.  This is required by the standard
  466.    because some ISO C functions will require linking with this object
  467.    file and the name space must not be polluted.  */
  468. # define open(name, flags)    open_not_cancel_2 (name, flags)
  469. # define close(fd)        close_not_cancel_no_status (fd)
  470. # define read(fd, buf, n)    read_not_cancel (fd, buf, n)
  471. # define mmap(addr, len, prot, flags, fd, offset) \
  472.   __mmap (addr, len, prot, flags, fd, offset)
  473. # define munmap(addr, len)    __munmap (addr, len)
  474. #endif
  475.  
  476. /* For those losing systems which don't have `alloca' we have to add
  477.    some additional code emulating it.  */
  478. #ifdef HAVE_ALLOCA
  479. # define freea(p) /* nothing */
  480. #else
  481. # define alloca(n) malloc (n)
  482. # define freea(p) free (p)
  483. #endif
  484.  
  485. /* For systems that distinguish between text and binary I/O.
  486.    O_BINARY is usually declared in <fcntl.h>. */
  487. #if !defined O_BINARY && defined _O_BINARY
  488.   /* For MSC-compatible compilers.  */
  489. # define O_BINARY _O_BINARY
  490. # define O_TEXT _O_TEXT
  491. #endif
  492. #ifdef __BEOS__
  493.   /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect.  */
  494. # undef O_BINARY
  495. # undef O_TEXT
  496. #endif
  497. /* On reasonable systems, binary I/O is the default.  */
  498. #ifndef O_BINARY
  499. # define O_BINARY 0
  500. #endif
  501.  
  502.  
  503. /* We need a sign, whether a new catalog was loaded, which can be associated
  504.    with all translations.  This is important if the translations are
  505.    cached by one of GCC's features.  */
  506. int _nl_msg_cat_cntr;
  507.  
  508.  
  509. /* Expand a system dependent string segment.  Return NULL if unsupported.  */
  510. static const char *
  511. get_sysdep_segment_value (const char *name)
  512. {
  513.   /* Test for an ISO C 99 section 7.8.1 format string directive.
  514.      Syntax:
  515.      P R I { d | i | o | u | x | X }
  516.      { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR }  */
  517.   /* We don't use a table of 14 times 6 'const char *' strings here, because
  518.      data relocations cost startup time.  */
  519.   if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I')
  520.     {
  521.       if (name[3] == 'd' || name[3] == 'i' || name[3] == 'o' || name[3] == 'u'
  522.       || name[3] == 'x' || name[3] == 'X')
  523.     {
  524.       if (name[4] == '8' && name[5] == '\0')
  525.         {
  526.           if (name[3] == 'd')
  527.         return PRId8;
  528.           if (name[3] == 'i')
  529.         return PRIi8;
  530.           if (name[3] == 'o')
  531.         return PRIo8;
  532.           if (name[3] == 'u')
  533.         return PRIu8;
  534.           if (name[3] == 'x')
  535.         return PRIx8;
  536.           if (name[3] == 'X')
  537.         return PRIX8;
  538.           abort ();
  539.         }
  540.       if (name[4] == '1' && name[5] == '6' && name[6] == '\0')
  541.         {
  542.           if (name[3] == 'd')
  543.         return PRId16;
  544.           if (name[3] == 'i')
  545.         return PRIi16;
  546.           if (name[3] == 'o')
  547.         return PRIo16;
  548.           if (name[3] == 'u')
  549.         return PRIu16;
  550.           if (name[3] == 'x')
  551.         return PRIx16;
  552.           if (name[3] == 'X')
  553.         return PRIX16;
  554.           abort ();
  555.         }
  556.       if (name[4] == '3' && name[5] == '2' && name[6] == '\0')
  557.         {
  558.           if (name[3] == 'd')
  559.         return PRId32;
  560.           if (name[3] == 'i')
  561.         return PRIi32;
  562.           if (name[3] == 'o')
  563.         return PRIo32;
  564.           if (name[3] == 'u')
  565.         return PRIu32;
  566.           if (name[3] == 'x')
  567.         return PRIx32;
  568.           if (name[3] == 'X')
  569.         return PRIX32;
  570.           abort ();
  571.         }
  572.       if (name[4] == '6' && name[5] == '4' && name[6] == '\0')
  573.         {
  574.           if (name[3] == 'd')
  575.         return PRId64;
  576.           if (name[3] == 'i')
  577.         return PRIi64;
  578.           if (name[3] == 'o')
  579.         return PRIo64;
  580.           if (name[3] == 'u')
  581.         return PRIu64;
  582.           if (name[3] == 'x')
  583.         return PRIx64;
  584.           if (name[3] == 'X')
  585.         return PRIX64;
  586.           abort ();
  587.         }
  588.       if (name[4] == 'L' && name[5] == 'E' && name[6] == 'A'
  589.           && name[7] == 'S' && name[8] == 'T')
  590.         {
  591.           if (name[9] == '8' && name[10] == '\0')
  592.         {
  593.           if (name[3] == 'd')
  594.             return PRIdLEAST8;
  595.           if (name[3] == 'i')
  596.             return PRIiLEAST8;
  597.           if (name[3] == 'o')
  598.             return PRIoLEAST8;
  599.           if (name[3] == 'u')
  600.             return PRIuLEAST8;
  601.           if (name[3] == 'x')
  602.             return PRIxLEAST8;
  603.           if (name[3] == 'X')
  604.             return PRIXLEAST8;
  605.           abort ();
  606.         }
  607.           if (name[9] == '1' && name[10] == '6' && name[11] == '\0')
  608.         {
  609.           if (name[3] == 'd')
  610.             return PRIdLEAST16;
  611.           if (name[3] == 'i')
  612.             return PRIiLEAST16;
  613.           if (name[3] == 'o')
  614.             return PRIoLEAST16;
  615.           if (name[3] == 'u')
  616.             return PRIuLEAST16;
  617.           if (name[3] == 'x')
  618.             return PRIxLEAST16;
  619.           if (name[3] == 'X')
  620.             return PRIXLEAST16;
  621.           abort ();
  622.         }
  623.           if (name[9] == '3' && name[10] == '2' && name[11] == '\0')
  624.         {
  625.           if (name[3] == 'd')
  626.             return PRIdLEAST32;
  627.           if (name[3] == 'i')
  628.             return PRIiLEAST32;
  629.           if (name[3] == 'o')
  630.             return PRIoLEAST32;
  631.           if (name[3] == 'u')
  632.             return PRIuLEAST32;
  633.           if (name[3] == 'x')
  634.             return PRIxLEAST32;
  635.           if (name[3] == 'X')
  636.             return PRIXLEAST32;
  637.           abort ();
  638.         }
  639.           if (name[9] == '6' && name[10] == '4' && name[11] == '\0')
  640.         {
  641.           if (name[3] == 'd')
  642.             return PRIdLEAST64;
  643.           if (name[3] == 'i')
  644.             return PRIiLEAST64;
  645.           if (name[3] == 'o')
  646.             return PRIoLEAST64;
  647.           if (name[3] == 'u')
  648.             return PRIuLEAST64;
  649.           if (name[3] == 'x')
  650.             return PRIxLEAST64;
  651.           if (name[3] == 'X')
  652.             return PRIXLEAST64;
  653.           abort ();
  654.         }
  655.         }
  656.       if (name[4] == 'F' && name[5] == 'A' && name[6] == 'S'
  657.           && name[7] == 'T')
  658.         {
  659.           if (name[8] == '8' && name[9] == '\0')
  660.         {
  661.           if (name[3] == 'd')
  662.             return PRIdFAST8;
  663.           if (name[3] == 'i')
  664.             return PRIiFAST8;
  665.           if (name[3] == 'o')
  666.             return PRIoFAST8;
  667.           if (name[3] == 'u')
  668.             return PRIuFAST8;
  669.           if (name[3] == 'x')
  670.             return PRIxFAST8;
  671.           if (name[3] == 'X')
  672.             return PRIXFAST8;
  673.           abort ();
  674.         }
  675.           if (name[8] == '1' && name[9] == '6' && name[10] == '\0')
  676.         {
  677.           if (name[3] == 'd')
  678.             return PRIdFAST16;
  679.           if (name[3] == 'i')
  680.             return PRIiFAST16;
  681.           if (name[3] == 'o')
  682.             return PRIoFAST16;
  683.           if (name[3] == 'u')
  684.             return PRIuFAST16;
  685.           if (name[3] == 'x')
  686.             return PRIxFAST16;
  687.           if (name[3] == 'X')
  688.             return PRIXFAST16;
  689.           abort ();
  690.         }
  691.           if (name[8] == '3' && name[9] == '2' && name[10] == '\0')
  692.         {
  693.           if (name[3] == 'd')
  694.             return PRIdFAST32;
  695.           if (name[3] == 'i')
  696.             return PRIiFAST32;
  697.           if (name[3] == 'o')
  698.             return PRIoFAST32;
  699.           if (name[3] == 'u')
  700.             return PRIuFAST32;
  701.           if (name[3] == 'x')
  702.             return PRIxFAST32;
  703.           if (name[3] == 'X')
  704.             return PRIXFAST32;
  705.           abort ();
  706.         }
  707.           if (name[8] == '6' && name[9] == '4' && name[10] == '\0')
  708.         {
  709.           if (name[3] == 'd')
  710.             return PRIdFAST64;
  711.           if (name[3] == 'i')
  712.             return PRIiFAST64;
  713.           if (name[3] == 'o')
  714.             return PRIoFAST64;
  715.           if (name[3] == 'u')
  716.             return PRIuFAST64;
  717.           if (name[3] == 'x')
  718.             return PRIxFAST64;
  719.           if (name[3] == 'X')
  720.             return PRIXFAST64;
  721.           abort ();
  722.         }
  723.         }
  724.       if (name[4] == 'M' && name[5] == 'A' && name[6] == 'X'
  725.           && name[7] == '\0')
  726.         {
  727.           if (name[3] == 'd')
  728.         return PRIdMAX;
  729.           if (name[3] == 'i')
  730.         return PRIiMAX;
  731.           if (name[3] == 'o')
  732.         return PRIoMAX;
  733.           if (name[3] == 'u')
  734.         return PRIuMAX;
  735.           if (name[3] == 'x')
  736.         return PRIxMAX;
  737.           if (name[3] == 'X')
  738.         return PRIXMAX;
  739.           abort ();
  740.         }
  741.       if (name[4] == 'P' && name[5] == 'T' && name[6] == 'R'
  742.           && name[7] == '\0')
  743.         {
  744.           if (name[3] == 'd')
  745.         return PRIdPTR;
  746.           if (name[3] == 'i')
  747.         return PRIiPTR;
  748.           if (name[3] == 'o')
  749.         return PRIoPTR;
  750.           if (name[3] == 'u')
  751.         return PRIuPTR;
  752.           if (name[3] == 'x')
  753.         return PRIxPTR;
  754.           if (name[3] == 'X')
  755.         return PRIXPTR;
  756.           abort ();
  757.         }
  758.     }
  759.     }
  760.   /* Test for a glibc specific printf() format directive flag.  */
  761.   if (name[0] == 'I' && name[1] == '\0')
  762.     {
  763. #if defined _LIBC || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
  764.       /* The 'I' flag, in numeric format directives, replaces ASCII digits
  765.      with the 'outdigits' defined in the LC_CTYPE locale facet.  This is
  766.      used for Farsi (Persian) and maybe Arabic.  */
  767.       return "I";
  768. #else
  769.       return "";
  770. #endif
  771.     }
  772.   /* Other system dependent strings are not valid.  */
  773.   return NULL;
  774. }
  775.  
  776. /* Load the message catalogs specified by FILENAME.  If it is no valid
  777.    message catalog do nothing.  */
  778. void
  779. internal_function
  780. _nl_load_domain (struct loaded_l10nfile *domain_file,
  781.          struct binding *domainbinding)
  782. {
  783.   __libc_lock_define_initialized_recursive (static, lock)
  784.   int fd = -1;
  785.   size_t size;
  786. #ifdef _LIBC
  787.   struct stat64 st;
  788. #else
  789.   struct stat st;
  790. #endif
  791.   struct mo_file_header *data = (struct mo_file_header *) -1;
  792.   int use_mmap = 0;
  793.   struct loaded_domain *domain;
  794.   int revision;
  795.   const char *nullentry;
  796.   size_t nullentrylen;
  797.  
  798.   __libc_lock_lock_recursive (lock);
  799.   if (domain_file->decided != 0)
  800.     {
  801.       /* There are two possibilities:
  802.  
  803.      + this is the same thread calling again during this initialization
  804.        via _nl_find_msg.  We have initialized everything this call needs.
  805.  
  806.      + this is another thread which tried to initialize this object.
  807.        Not necessary anymore since if the lock is available this
  808.        is finished.
  809.       */
  810.       goto done;
  811.     }
  812.  
  813.   domain_file->decided = -1;
  814.   domain_file->data = NULL;
  815.  
  816.   /* Note that it would be useless to store domainbinding in domain_file
  817.      because domainbinding might be == NULL now but != NULL later (after
  818.      a call to bind_textdomain_codeset).  */
  819.  
  820.   /* If the record does not represent a valid locale the FILENAME
  821.      might be NULL.  This can happen when according to the given
  822.      specification the locale file name is different for XPG and CEN
  823.      syntax.  */
  824.   if (domain_file->filename == NULL)
  825.     goto out;
  826.  
  827.   /* Try to open the addressed file.  */
  828.   fd = open (domain_file->filename, O_RDONLY | O_BINARY);
  829.   if (fd == -1)
  830.     goto out;
  831.  
  832.   /* We must know about the size of the file.  */
  833.   if (
  834. #ifdef _LIBC
  835.       __builtin_expect (fstat64 (fd, &st) != 0, 0)
  836. #else
  837.       __builtin_expect (fstat (fd, &st) != 0, 0)
  838. #endif
  839.       || __builtin_expect ((size = (size_t) st.st_size) != st.st_size, 0)
  840.       || __builtin_expect (size < sizeof (struct mo_file_header), 0))
  841.     /* Something went wrong.  */
  842.     goto out;
  843.  
  844. #ifdef HAVE_MMAP
  845.   /* Now we are ready to load the file.  If mmap() is available we try
  846.      this first.  If not available or it failed we try to load it.  */
  847.   data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
  848.                      MAP_PRIVATE, fd, 0);
  849.  
  850.   if (__builtin_expect (data != (struct mo_file_header *) -1, 1))
  851.     {
  852.       /* mmap() call was successful.  */
  853.       close (fd);
  854.       fd = -1;
  855.       use_mmap = 1;
  856.     }
  857. #endif
  858.  
  859.   /* If the data is not yet available (i.e. mmap'ed) we try to load
  860.      it manually.  */
  861.   if (data == (struct mo_file_header *) -1)
  862.     {
  863.       size_t to_read;
  864.       char *read_ptr;
  865.  
  866.       data = (struct mo_file_header *) malloc (size);
  867.       if (data == NULL)
  868.     goto out;
  869.  
  870.       to_read = size;
  871.       read_ptr = (char *) data;
  872.       do
  873.     {
  874.       long int nb = (long int) read (fd, read_ptr, to_read);
  875.       if (nb <= 0)
  876.         {
  877. #ifdef EINTR
  878.           if (nb == -1 && errno == EINTR)
  879.         continue;
  880. #endif
  881.           goto out;
  882.         }
  883.       read_ptr += nb;
  884.       to_read -= nb;
  885.     }
  886.       while (to_read > 0);
  887.  
  888.       close (fd);
  889.       fd = -1;
  890.     }
  891.  
  892.   /* Using the magic number we can test whether it really is a message
  893.      catalog file.  */
  894.   if (__builtin_expect (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED,
  895.             0))
  896.     {
  897.       /* The magic number is wrong: not a message catalog file.  */
  898. #ifdef HAVE_MMAP
  899.       if (use_mmap)
  900.     munmap ((caddr_t) data, size);
  901.       else
  902. #endif
  903.     free (data);
  904.       goto out;
  905.     }
  906.  
  907.   domain = (struct loaded_domain *) malloc (sizeof (struct loaded_domain));
  908.   if (domain == NULL)
  909.     goto out;
  910.   domain_file->data = domain;
  911.  
  912.   domain->data = (char *) data;
  913.   domain->use_mmap = use_mmap;
  914.   domain->mmap_size = size;
  915.   domain->must_swap = data->magic != _MAGIC;
  916.   domain->malloced = NULL;
  917.  
  918.   /* Fill in the information about the available tables.  */
  919.   revision = W (domain->must_swap, data->revision);
  920.   /* We support only the major revisions 0 and 1.  */
  921.   switch (revision >> 16)
  922.     {
  923.     case 0:
  924.     case 1:
  925.       domain->nstrings = W (domain->must_swap, data->nstrings);
  926.       domain->orig_tab = (const struct string_desc *)
  927.     ((char *) data + W (domain->must_swap, data->orig_tab_offset));
  928.       domain->trans_tab = (const struct string_desc *)
  929.     ((char *) data + W (domain->must_swap, data->trans_tab_offset));
  930.       domain->hash_size = W (domain->must_swap, data->hash_tab_size);
  931.       domain->hash_tab =
  932.     (domain->hash_size > 2
  933.      ? (const nls_uint32 *)
  934.        ((char *) data + W (domain->must_swap, data->hash_tab_offset))
  935.      : NULL);
  936.       domain->must_swap_hash_tab = domain->must_swap;
  937.  
  938.       /* Now dispatch on the minor revision.  */
  939.       switch (revision & 0xffff)
  940.     {
  941.     case 0:
  942.       domain->n_sysdep_strings = 0;
  943.       domain->orig_sysdep_tab = NULL;
  944.       domain->trans_sysdep_tab = NULL;
  945.       break;
  946.     case 1:
  947.     default:
  948.       {
  949.         nls_uint32 n_sysdep_strings;
  950.  
  951.         if (domain->hash_tab == NULL)
  952.           /* This is invalid.  These minor revisions need a hash table.  */
  953.           goto invalid;
  954.  
  955.         n_sysdep_strings =
  956.           W (domain->must_swap, data->n_sysdep_strings);
  957.         if (n_sysdep_strings > 0)
  958.           {
  959.         nls_uint32 n_sysdep_segments;
  960.         const struct sysdep_segment *sysdep_segments;
  961.         const char **sysdep_segment_values;
  962.         const nls_uint32 *orig_sysdep_tab;
  963.         const nls_uint32 *trans_sysdep_tab;
  964.         nls_uint32 n_inmem_sysdep_strings;
  965.         size_t memneed;
  966.         char *mem;
  967.         struct sysdep_string_desc *inmem_orig_sysdep_tab;
  968.         struct sysdep_string_desc *inmem_trans_sysdep_tab;
  969.         nls_uint32 *inmem_hash_tab;
  970.         unsigned int i, j;
  971.  
  972.         /* Get the values of the system dependent segments.  */
  973.         n_sysdep_segments =
  974.           W (domain->must_swap, data->n_sysdep_segments);
  975.         sysdep_segments = (const struct sysdep_segment *)
  976.           ((char *) data
  977.            + W (domain->must_swap, data->sysdep_segments_offset));
  978.         sysdep_segment_values =
  979.           alloca (n_sysdep_segments * sizeof (const char *));
  980.         for (i = 0; i < n_sysdep_segments; i++)
  981.           {
  982.             const char *name =
  983.               (char *) data
  984.               + W (domain->must_swap, sysdep_segments[i].offset);
  985.             nls_uint32 namelen =
  986.               W (domain->must_swap, sysdep_segments[i].length);
  987.  
  988.             if (!(namelen > 0 && name[namelen - 1] == '\0'))
  989.               {
  990.             freea (sysdep_segment_values);
  991.             goto invalid;
  992.               }
  993.  
  994.             sysdep_segment_values[i] = get_sysdep_segment_value (name);
  995.           }
  996.  
  997.         orig_sysdep_tab = (const nls_uint32 *)
  998.           ((char *) data
  999.            + W (domain->must_swap, data->orig_sysdep_tab_offset));
  1000.         trans_sysdep_tab = (const nls_uint32 *)
  1001.           ((char *) data
  1002.            + W (domain->must_swap, data->trans_sysdep_tab_offset));
  1003.  
  1004.         /* Compute the amount of additional memory needed for the
  1005.            system dependent strings and the augmented hash table.
  1006.            At the same time, also drop string pairs which refer to
  1007.            an undefined system dependent segment.  */
  1008.         n_inmem_sysdep_strings = 0;
  1009.         memneed = domain->hash_size * sizeof (nls_uint32);
  1010.         for (i = 0; i < n_sysdep_strings; i++)
  1011.           {
  1012.             int valid = 1;
  1013.             size_t needs[2];
  1014.  
  1015.             for (j = 0; j < 2; j++)
  1016.               {
  1017.             const struct sysdep_string *sysdep_string =
  1018.               (const struct sysdep_string *)
  1019.               ((char *) data
  1020.                + W (domain->must_swap,
  1021.                 j == 0
  1022.                 ? orig_sysdep_tab[i]
  1023.                 : trans_sysdep_tab[i]));
  1024.             size_t need = 0;
  1025.             const struct segment_pair *p = sysdep_string->segments;
  1026.  
  1027.             if (W (domain->must_swap, p->sysdepref) != SEGMENTS_END)
  1028.               for (p = sysdep_string->segments;; p++)
  1029.                 {
  1030.                   nls_uint32 sysdepref;
  1031.  
  1032.                   need += W (domain->must_swap, p->segsize);
  1033.  
  1034.                   sysdepref = W (domain->must_swap, p->sysdepref);
  1035.                   if (sysdepref == SEGMENTS_END)
  1036.                 break;
  1037.  
  1038.                   if (sysdepref >= n_sysdep_segments)
  1039.                 {
  1040.                   /* Invalid.  */
  1041.                   freea (sysdep_segment_values);
  1042.                   goto invalid;
  1043.                 }
  1044.  
  1045.                   if (sysdep_segment_values[sysdepref] == NULL)
  1046.                 {
  1047.                   /* This particular string pair is invalid.  */
  1048.                   valid = 0;
  1049.                   break;
  1050.                 }
  1051.  
  1052.                   need += strlen (sysdep_segment_values[sysdepref]);
  1053.                 }
  1054.  
  1055.             needs[j] = need;
  1056.             if (!valid)
  1057.               break;
  1058.               }
  1059.  
  1060.             if (valid)
  1061.               {
  1062.             n_inmem_sysdep_strings++;
  1063.             memneed += needs[0] + needs[1];
  1064.               }
  1065.           }
  1066.         memneed += 2 * n_inmem_sysdep_strings
  1067.                * sizeof (struct sysdep_string_desc);
  1068.  
  1069.         if (n_inmem_sysdep_strings > 0)
  1070.           {
  1071.             unsigned int k;
  1072.  
  1073.             /* Allocate additional memory.  */
  1074.             mem = (char *) malloc (memneed);
  1075.             if (mem == NULL)
  1076.               goto invalid;
  1077.  
  1078.             domain->malloced = mem;
  1079.             inmem_orig_sysdep_tab = (struct sysdep_string_desc *) mem;
  1080.             mem += n_inmem_sysdep_strings
  1081.                * sizeof (struct sysdep_string_desc);
  1082.             inmem_trans_sysdep_tab = (struct sysdep_string_desc *) mem;
  1083.             mem += n_inmem_sysdep_strings
  1084.                * sizeof (struct sysdep_string_desc);
  1085.             inmem_hash_tab = (nls_uint32 *) mem;
  1086.             mem += domain->hash_size * sizeof (nls_uint32);
  1087.  
  1088.             /* Compute the system dependent strings.  */
  1089.             k = 0;
  1090.             for (i = 0; i < n_sysdep_strings; i++)
  1091.               {
  1092.             int valid = 1;
  1093.  
  1094.             for (j = 0; j < 2; j++)
  1095.               {
  1096.                 const struct sysdep_string *sysdep_string =
  1097.                   (const struct sysdep_string *)
  1098.                   ((char *) data
  1099.                    + W (domain->must_swap,
  1100.                     j == 0
  1101.                     ? orig_sysdep_tab[i]
  1102.                     : trans_sysdep_tab[i]));
  1103.                 const struct segment_pair *p =
  1104.                   sysdep_string->segments;
  1105.  
  1106.                 if (W (domain->must_swap, p->sysdepref)
  1107.                 != SEGMENTS_END)
  1108.                   for (p = sysdep_string->segments;; p++)
  1109.                 {
  1110.                   nls_uint32 sysdepref;
  1111.  
  1112.                   sysdepref =
  1113.                     W (domain->must_swap, p->sysdepref);
  1114.                   if (sysdepref == SEGMENTS_END)
  1115.                     break;
  1116.  
  1117.                   if (sysdep_segment_values[sysdepref] == NULL)
  1118.                     {
  1119.                       /* This particular string pair is
  1120.                      invalid.  */
  1121.                       valid = 0;
  1122.                       break;
  1123.                     }
  1124.                 }
  1125.  
  1126.                 if (!valid)
  1127.                   break;
  1128.               }
  1129.  
  1130.             if (valid)
  1131.               {
  1132.                 for (j = 0; j < 2; j++)
  1133.                   {
  1134.                 const struct sysdep_string *sysdep_string =
  1135.                   (const struct sysdep_string *)
  1136.                   ((char *) data
  1137.                    + W (domain->must_swap,
  1138.                     j == 0
  1139.                     ? orig_sysdep_tab[i]
  1140.                     : trans_sysdep_tab[i]));
  1141.                 const char *static_segments =
  1142.                   (char *) data
  1143.                   + W (domain->must_swap, sysdep_string->offset);
  1144.                 const struct segment_pair *p =
  1145.                   sysdep_string->segments;
  1146.  
  1147.                 /* Concatenate the segments, and fill
  1148.                    inmem_orig_sysdep_tab[k] (for j == 0) and
  1149.                    inmem_trans_sysdep_tab[k] (for j == 1).  */
  1150.  
  1151.                 struct sysdep_string_desc *inmem_tab_entry =
  1152.                   (j == 0
  1153.                    ? inmem_orig_sysdep_tab
  1154.                    : inmem_trans_sysdep_tab)
  1155.                   + k;
  1156.  
  1157.                 if (W (domain->must_swap, p->sysdepref)
  1158.                     == SEGMENTS_END)
  1159.                   {
  1160.                     /* Only one static segment.  */
  1161.                     inmem_tab_entry->length =
  1162.                       W (domain->must_swap, p->segsize);
  1163.                     inmem_tab_entry->pointer = static_segments;
  1164.                   }
  1165.                 else
  1166.                   {
  1167.                     inmem_tab_entry->pointer = mem;
  1168.  
  1169.                     for (p = sysdep_string->segments;; p++)
  1170.                       {
  1171.                     nls_uint32 segsize =
  1172.                       W (domain->must_swap, p->segsize);
  1173.                     nls_uint32 sysdepref =
  1174.                       W (domain->must_swap, p->sysdepref);
  1175.                     size_t n;
  1176.  
  1177.                     if (segsize > 0)
  1178.                       {
  1179.                         memcpy (mem, static_segments, segsize);
  1180.                         mem += segsize;
  1181.                         static_segments += segsize;
  1182.                       }
  1183.  
  1184.                     if (sysdepref == SEGMENTS_END)
  1185.                       break;
  1186.  
  1187.                     n = strlen (sysdep_segment_values[sysdepref]);
  1188.                     memcpy (mem, sysdep_segment_values[sysdepref], n);
  1189.                     mem += n;
  1190.                       }
  1191.  
  1192.                     inmem_tab_entry->length =
  1193.                       mem - inmem_tab_entry->pointer;
  1194.                   }
  1195.                   }
  1196.  
  1197.                 k++;
  1198.               }
  1199.               }
  1200.             if (k != n_inmem_sysdep_strings)
  1201.               abort ();
  1202.  
  1203.             /* Compute the augmented hash table.  */
  1204.             for (i = 0; i < domain->hash_size; i++)
  1205.               inmem_hash_tab[i] =
  1206.             W (domain->must_swap_hash_tab, domain->hash_tab[i]);
  1207.             for (i = 0; i < n_inmem_sysdep_strings; i++)
  1208.               {
  1209.             const char *msgid = inmem_orig_sysdep_tab[i].pointer;
  1210.             nls_uint32 hash_val = __hash_string (msgid);
  1211.             nls_uint32 idx = hash_val % domain->hash_size;
  1212.             nls_uint32 incr =
  1213.               1 + (hash_val % (domain->hash_size - 2));
  1214.  
  1215.             for (;;)
  1216.               {
  1217.                 if (inmem_hash_tab[idx] == 0)
  1218.                   {
  1219.                 /* Hash table entry is empty.  Use it.  */
  1220.                 inmem_hash_tab[idx] = 1 + domain->nstrings + i;
  1221.                 break;
  1222.                   }
  1223.  
  1224.                 if (idx >= domain->hash_size - incr)
  1225.                   idx -= domain->hash_size - incr;
  1226.                 else
  1227.                   idx += incr;
  1228.               }
  1229.               }
  1230.  
  1231.             domain->n_sysdep_strings = n_inmem_sysdep_strings;
  1232.             domain->orig_sysdep_tab = inmem_orig_sysdep_tab;
  1233.             domain->trans_sysdep_tab = inmem_trans_sysdep_tab;
  1234.  
  1235.             domain->hash_tab = inmem_hash_tab;
  1236.             domain->must_swap_hash_tab = 0;
  1237.           }
  1238.         else
  1239.           {
  1240.             domain->n_sysdep_strings = 0;
  1241.             domain->orig_sysdep_tab = NULL;
  1242.             domain->trans_sysdep_tab = NULL;
  1243.           }
  1244.  
  1245.         freea (sysdep_segment_values);
  1246.           }
  1247.         else
  1248.           {
  1249.         domain->n_sysdep_strings = 0;
  1250.         domain->orig_sysdep_tab = NULL;
  1251.         domain->trans_sysdep_tab = NULL;
  1252.           }
  1253.       }
  1254.       break;
  1255.     }
  1256.       break;
  1257.     default:
  1258.       /* This is an invalid revision.  */
  1259.     invalid:
  1260.       /* This is an invalid .mo file.  */
  1261.       if (domain->malloced)
  1262.     free (domain->malloced);
  1263. #ifdef HAVE_MMAP
  1264.       if (use_mmap)
  1265.     munmap ((caddr_t) data, size);
  1266.       else
  1267. #endif
  1268.     free (data);
  1269.       free (domain);
  1270.       domain_file->data = NULL;
  1271.       goto out;
  1272.     }
  1273.  
  1274.   /* No caches of converted translations so far.  */
  1275.   domain->conversions = NULL;
  1276.   domain->nconversions = 0;
  1277.  
  1278.   /* Get the header entry and look for a plural specification.  */
  1279. #ifdef IN_LIBGLOCALE
  1280.   nullentry =
  1281.     _nl_find_msg (domain_file, domainbinding, NULL, "", &nullentrylen);
  1282. #else
  1283.   nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
  1284. #endif
  1285.   EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
  1286.  
  1287.  out:
  1288.   if (fd != -1)
  1289.     close (fd);
  1290.  
  1291.   domain_file->decided = 1;
  1292.  
  1293.  done:
  1294.   __libc_lock_unlock_recursive (lock);
  1295. }
  1296.  
  1297.  
  1298. #ifdef _LIBC
  1299. void
  1300. internal_function __libc_freeres_fn_section
  1301. _nl_unload_domain (struct loaded_domain *domain)
  1302. {
  1303.   size_t i;
  1304.  
  1305.   if (domain->plural != &__gettext_germanic_plural)
  1306.     __gettext_free_exp (domain->plural);
  1307.  
  1308.   for (i = 0; i < domain->nconversions; i++)
  1309.     {
  1310.       struct converted_domain *convd = &domain->conversions[i];
  1311.  
  1312.       free (convd->encoding);
  1313.       if (convd->conv_tab != NULL && convd->conv_tab != (char **) -1)
  1314.     free (convd->conv_tab);
  1315.       if (convd->conv != (__gconv_t) -1)
  1316.     __gconv_close (convd->conv);
  1317.     }
  1318.   if (domain->conversions != NULL)
  1319.     free (domain->conversions);
  1320.  
  1321.   if (domain->malloced)
  1322.     free (domain->malloced);
  1323.  
  1324. # ifdef _POSIX_MAPPED_FILES
  1325.   if (domain->use_mmap)
  1326.     munmap ((caddr_t) domain->data, domain->mmap_size);
  1327.   else
  1328. # endif    /* _POSIX_MAPPED_FILES */
  1329.     free ((void *) domain->data);
  1330.  
  1331.   free (domain);
  1332. }
  1333. #endif
  1334.